
Imports System.IO

Module angel

    Public Const sleeptime As Int32 = 1000

    Public Sub main(ByVal args() As String)
        On Error Resume Next

        If args.Length = 0 Then
            raiseError("argument error, angel monitor1 monitor1.arguments ... monitorN monitorN.arguments, " + _
                       "monitoring application should be in 'PATH' or with full path", errorHandle.errorType.critical)
        Else
            registerConsoleExtHandle()
            raiseError("angel started, sleeptime is set to " + Convert.ToString(sleeptime) + " by const.")
            Dim appsCount As Int32 = (args.Length + 1) >> 1
            Dim apps(appsCount - 1) As String
            Dim appnames(appsCount - 1) As String
            Dim arguments(appsCount - 1) As String
            Dim procs(appsCount - 1) As Process
            Dim i As Int32
            Console.WriteLine("monitoring applications list")
            For i = 0 To appsCount
                apps(i) = fullpath(args(i << 1))
                appnames(i) = Path.GetFileNameWithoutExtension(args(i << 1))
                If (i << 1) + 1 < args.Length Then
                    arguments(i) = args((i << 1) + 1)
                End If

                Console.WriteLine(appnames(i) + character.tab + apps(i) + character.blank + arguments(i))
            Next

            Console.Title() = applicationName()
            While Not consoleExtSignal()
                For i = 0 To appsCount - 1
                    If procs(i) Is Nothing OrElse procs(i).HasExited Then
                        raiseError("no application [" + appnames(i) + "] found, " + _
                                   "restart with [" + apps(i) + "]", errorHandle.errorType.information)
                        debugpause()

                        If Not startprocess(procs(i), apps(i), arguments(i), _
                                            Function(ByRef proc As Process) As Boolean
                                                proc.StartInfo().UseShellExecute() = False
                                                Return True
                                            End Function) Then
                            raiseError("failed to start application, [" + apps(i) + " " + arguments(i) + "]", _
                                       errorHandle.errorType.critical)
                        Else
                            Console.Title() += "[" + apps(i) + ":" + Convert.ToString(procs(i).Id()) + "]"
                        End If
                    End If
                Next

                sleep(sleeptime)
            End While

            raiseError("caught console cancel signal, start shutdown all monitor applications.")
            For i = 0 To appsCount - 1
                raiseError("kill applications [" + appnames(i) + "], pid " + Convert.ToString(procs(i).Id))
                closeProcess(procs(i), defaultCloseProcessWaittime - 5000, False)
            Next

            consoleExtHandleFinish()
        End If

        forceQuit(0)
    End Sub

End Module
